package com.prd.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.prd.config.LoginInterceptor;
import com.prd.constant.CheckStatus;
import com.prd.mapper.EntBudgetMapper;
import com.prd.model.*;
import com.prd.service.*;
import com.prd.util.StringsUtils;
import com.prd.util.UserInfoUtil;
import com.prd.vo.EntBudgetVo;
import com.prd.vo.UserBaseVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class EntBudgetServiceImpl extends ServiceImpl<EntBudgetMapper, EntBudget> implements EntBudgetService {

    @Autowired
    private EntBudgetMapper entBudgetMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private EntBudgetCourseService entBudgetCourseService;

    @Autowired
    private EntBudgetNapeService entBudgetNapeService;

    @Autowired
    private EntBudgetSubentryService entBudgetSubentryService;

    @Autowired
    private EntBudgetCheckService entBudgetCheckService;

    @Override
    public int insertInfo(EntBudget entBudget) {
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        BeanUtils.copyProperties(UserInfoUtil.recordInfo(loginUser.getId(), loginUser.getName(), true), entBudget);
        entBudget.setNumber(String.valueOf(System.nanoTime()));
        entBudget.setStatus(CheckStatus.ONE.getCode());
        return entBudgetMapper.insert(entBudget);
    }

    @Override
    public int updateInfo(EntBudget entBudget) {
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        BeanUtils.copyProperties(UserInfoUtil.recordInfo(loginUser.getId(), loginUser.getName(), false), entBudget);
        return entBudgetMapper.updateById(entBudget);
    }

    @Override
    public List<EntBudget> listInfo(String day, Integer catalog) {
        LambdaQueryWrapper<EntBudget> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.apply(StringUtils.isNotBlank(day), "DATE(end_time) = {0}", day);
        //全部
        if (catalog == 0) {

        } else if (catalog == 1) {//草稿
            queryWrapper.eq(EntBudget::getIsDraft, 1);
        } else if (catalog == 2) {//待审批
            queryWrapper.eq(EntBudget::getStatus, CheckStatus.ONE.getCode());
        } else if (catalog == 3) {//不通过
            queryWrapper.eq(EntBudget::getStatus, CheckStatus.THREE.getCode());
        } else if (catalog == 4) {//执行中
            queryWrapper.eq(EntBudget::getStatus, CheckStatus.TWO.getCode());
        } else if (catalog == 5) {//执行完成
            queryWrapper.eq(EntBudget::getStatus, 4);
        } else {
            throw new RuntimeException("找不到类型！");
        }
        List<EntBudget> list = entBudgetMapper.selectList(queryWrapper);
        for (EntBudget budget : list) {
            budget.setEmploy(userService.listName(Long.parseLong(budget.getEmploy())).getMerge());
        }
        return list;
    }

    @Transactional
    @Override
    public int saveOrUpdateInfo(EntBudget entBudget, Boolean boo) {
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        int i = 0;
        if (entBudget.getId() != null) {
            i = updateInfo(entBudget);
        } else {
            i = insertInfo(entBudget);
        }
        if (entBudget.getBudgetCourse() != null && entBudget.getBudgetCourse().size() > 0) {
            List<EntBudgetCourse> budgetCourseList = entBudget.getBudgetCourse();
            for (EntBudgetCourse entBudgetCourse : budgetCourseList) {
                if (entBudgetCourse.getId() != null) {
                    boo = false;
                } else {
                    boo = true;
                }
                BeanUtils.copyProperties(UserInfoUtil.recordInfo(loginUser.getId(), loginUser.getName(), boo), entBudgetCourse);
                entBudgetCourse.setBudgetId(entBudget.getId());
                entBudgetCourseService.saveOrUpdate(entBudgetCourse);
                if (entBudgetCourse.getBudgetNape() != null && entBudgetCourse.getBudgetNape().size() > 0) {
                    List<EntBudgetNape> budgetNapeList = entBudgetCourse.getBudgetNape();
                    for (EntBudgetNape entBudgetNape : budgetNapeList) {
                        if (entBudgetNape.getId() != null) {
                            boo = false;
                        } else {
                            boo = true;
                        }
                        BeanUtils.copyProperties(UserInfoUtil.recordInfo(loginUser.getId(), loginUser.getName(), boo), entBudgetNape);
                        entBudgetNape.setCourseId(entBudgetCourse.getId());
                        entBudgetNapeService.saveOrUpdate(entBudgetNape);
                        if (entBudgetNape.getBudgetSubentry() != null && entBudgetNape.getBudgetSubentry().size() > 0) {
                            List<EntBudgetSubentry> budgetSubentryList = entBudgetNape.getBudgetSubentry();
                            for (EntBudgetSubentry entBudgetSubentry : budgetSubentryList) {
                                if (entBudgetSubentry.getId() != null) {
                                    boo = false;
                                } else {
                                    boo = true;
                                }
                                BeanUtils.copyProperties(UserInfoUtil.recordInfo(loginUser.getId(), loginUser.getName(), boo), entBudgetSubentry);
                                entBudgetSubentry.setNapeId(entBudgetNape.getId());
                                entBudgetSubentryService.saveOrUpdate(entBudgetSubentry);
                            }
                        }
                    }
                }
            }
        }
        return i;
    }

    @Override
    public EntBudgetVo details(Long id) {
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        EntBudgetVo entBudgetVo = new EntBudgetVo();
        EntBudget entBudget = entBudgetMapper.selectById(id);
        if (entBudget == null) {
            throw new RuntimeException("记录没有找到！");
        }
        LambdaQueryWrapper<EntBudgetCourse> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(EntBudgetCourse::getBudgetId, entBudget.getId());
        List<EntBudgetCourse> budgetCourseList = entBudgetCourseService.list(queryWrapper);
        for (EntBudgetCourse entBudgetCourse : budgetCourseList) {
            LambdaQueryWrapper<EntBudgetNape> queryWrapper1 = new LambdaQueryWrapper();
            queryWrapper1.eq(EntBudgetNape::getCourseId, entBudgetCourse.getId());
            List<EntBudgetNape> budgetNapeList = entBudgetNapeService.list(queryWrapper1);
            for (EntBudgetNape entBudgetNape : budgetNapeList) {
                LambdaQueryWrapper<EntBudgetSubentry> queryWrapper2 = new LambdaQueryWrapper();
                queryWrapper2.eq(EntBudgetSubentry::getNapeId, entBudgetNape.getId());
                List<EntBudgetSubentry> budgetSubentryList = entBudgetSubentryService.list(queryWrapper2);
                entBudgetNape.setBudgetSubentry(budgetSubentryList);
            }
            entBudgetCourse.setBudgetNape(budgetNapeList);
        }
        entBudget.setBudgetCourse(budgetCourseList);
        BeanUtils.copyProperties(entBudget, entBudgetVo);

        //获取用户信息
        List<Long> arrayList = new ArrayList<>();
        List<Long> makes = Arrays.asList(StringsUtils.convert(entBudget.getMake().split(",")));
        arrayList.addAll(makes);
        arrayList.add(StringsUtils.isNotBlank(entBudget.getEmploy()) ? 0 : Long.valueOf(entBudget.getEmploy()));
        arrayList.add(StringsUtils.isNotBlank(entBudget.getAuditor()) ? 0 : Long.valueOf(entBudget.getAuditor()));
        arrayList.add(StringsUtils.isNotBlank(entBudget.getFinance()) ? 0 : Long.valueOf(entBudget.getFinance()));
        arrayList.add(StringsUtils.isNotBlank(entBudget.getBudget()) ? 0 : Long.valueOf(entBudget.getBudget()));
        arrayList.add(StringsUtils.isNotBlank(entBudget.getActual()) ? 0 : Long.valueOf(entBudget.getActual()));
        arrayList.add(StringsUtils.isNotBlank(entBudget.getRatify()) ? 0 : Long.valueOf(entBudget.getRatify()));
        arrayList.stream().distinct().collect(Collectors.toList());
        List<UserBaseVo> listUser = userService.listName(arrayList.toArray(new Long[arrayList.size()]));
        List<String> listMake = new ArrayList<>();
        for (UserBaseVo userBaseVo : listUser) {
            if (entBudget.getEmploy().equals(userBaseVo.getId().toString())) {
                entBudgetVo.setEmploy(userBaseVo.getName());
            }
            if (entBudget.getAuditor().equals(userBaseVo.getId().toString())) {
                entBudgetVo.setAuditor(userBaseVo.getName());
            }
            if (entBudget.getFinance().equals(userBaseVo.getId().toString())) {
                entBudgetVo.setFinance(userBaseVo.getName());
            }
            if (entBudget.getBudget().equals(userBaseVo.getId().toString())) {
                entBudgetVo.setBudget(userBaseVo.getName());
            }
            if (entBudget.getActual().equals(userBaseVo.getId().toString())) {
                entBudgetVo.setActual(userBaseVo.getName());
            }
            if (entBudget.getRatify().equals(userBaseVo.getId().toString())) {
                entBudgetVo.setRatify(userBaseVo.getName());
            }
            if (makes.contains(userBaseVo.getId())) {
                listMake.add(userBaseVo.getMerge());
            }
        }
        entBudgetVo.setMakes(listMake);

        LambdaQueryWrapper<EntBudgetCheck> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(EntBudgetCheck::getBudgetId, entBudget.getId());
        lambdaQueryWrapper.eq(EntBudgetCheck::getCreateId, loginUser.getId());
        entBudgetVo.setBudgetCheckList(entBudgetCheckService.list(lambdaQueryWrapper));
        return entBudgetVo;
    }

    @Override
    public int applyAudit(Long id) {
        EntBudget entBudget = entBudgetMapper.selectById(id);
        if (entBudget == null) {
            throw new RuntimeException("记录没有找到！");
        }
        entBudget.setIsDraft(2);
        entBudget.setStatus(CheckStatus.ONE.getCode());
        return updateInfo(entBudget);
    }

    @Override
    public int pass(EntBudgetCheck entBudgetCheck) {
        EntBudget entBudget = entBudgetMapper.selectById(entBudgetCheck.getBudgetId());
        if (entBudget == null) {
            throw new RuntimeException("记录没有找到！");
        }
        entBudget.setStatus(entBudgetCheck.getType());
        entBudgetCheckService.insertInfo(entBudgetCheck);
        return updateInfo(entBudget);
    }

    @Override
    public int addMake(Long budgetId, Long[] makes) {
        EntBudget entBudget = entBudgetMapper.selectById(budgetId);
        if (entBudget == null) {
            throw new RuntimeException("记录没有找到！");
        }
        if (StringUtils.isNotBlank(entBudget.getMake())) {
            entBudget.setMake(entBudget.getMake() + "," + makes.toString());
        } else {
            entBudget.setMake(makes.toString());
        }
        return updateInfo(entBudget);
    }

    @Override
    public JSONArray jurisdiction(Long budgetId) {
        JSONArray jsonArray = new JSONArray();
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        EntBudget entBudget = entBudgetMapper.selectById(budgetId);
        if (entBudget == null) {
            throw new RuntimeException("记录没有找到！");
        }
        if (entBudget.getEmploy().equals(loginUser.getId().toString())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "employ");
            jsonObject.put("name", "使用人");
            jsonArray.add(jsonObject);
        }
        if (entBudget.getAuditor().equals(loginUser.getId().toString())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "auditor");
            jsonObject.put("name", "审核人");
            jsonArray.add(jsonObject);
        }
        if (entBudget.getFinance().equals(loginUser.getId().toString())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "finance");
            jsonObject.put("name", "财务负责人");
            jsonArray.add(jsonObject);
        }
        if (entBudget.getBudget().equals(loginUser.getId().toString())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "budget");
            jsonObject.put("name", "预算审计");
            jsonArray.add(jsonObject);
        }
        if (entBudget.getActual().equals(loginUser.getId().toString())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "actual");
            jsonObject.put("name", "决算审计");
            jsonArray.add(jsonObject);
        }
        if (entBudget.getRatify().equals(loginUser.getId().toString())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", "ratify");
            jsonObject.put("name", "批准");
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }

    @Override
    public int addOpinion(EntBudgetCheck entBudgetCheck) {
        return entBudgetCheckService.insertInfo(entBudgetCheck);
    }
}
